// utils/request.js
const TOKEN_KEY = 'access_token';
const REFRESH_TOKEN_KEY = 'refresh_token';
let isRefreshing = false; // 防止重复刷新token
let requests = []; // 存储等待刷新token的请求队列

// 默认配置
const defaultConfig = {
  // baseURL: 'http://192.168.14.26:8012',
  baseURL: 'http://zxswjdsk.hjqdsj.cn/admin',
  timeout: 15000,
  header: {
    'Content-Type': 'application/json'
  },
  showLoading: true,
  loadingTitle: '加载中...'
};

// 当前配置
let currentConfig = { ...defaultConfig };
// 不需要携带token的接口列表
const excludeList = ['/admin/login/password']

// Token 管理工具 - 核心修复点：确保存储和读取的一致性
export const getToken = () => {
  try {
    const token = uni.getStorageSync(TOKEN_KEY);
    // 增加日志便于调试
    console.log('获取access_token:', token ? '存在' : '不存在');
    return token || '';
  } catch (e) {
    console.error('获取access_token失败:', e);
    return '';
  }
};

export const getRefreshToken = () => {
  try {
    const token = uni.getStorageSync(REFRESH_TOKEN_KEY);
    return token || '';
  } catch (e) {
    console.error('获取refresh_token失败:', e);
    return '';
  }
};

export const setToken = (token) => {
  try {
    // 存储前验证token有效性
    if (token && typeof token === 'string' && token.trim() !== '') {
      uni.setStorageSync(TOKEN_KEY, token);
      console.log('存储access_token成功:', token.substring(0, 10) + '...'); // 只显示部分token
    } else {
      console.error('存储的access_token无效:', token);
    }
  } catch (e) {
    console.error('存储access_token失败:', e);
  }
};

export const setRefreshToken = (token) => {
  try {
    if (token && typeof token === 'string' && token.trim() !== '') {
      uni.setStorageSync(REFRESH_TOKEN_KEY, token);
    } else {
      console.error('存储的refresh_token无效:', token);
    }
  } catch (e) {
    console.error('存储refresh_token失败:', e);
  }
};

export const removeToken = () => {
  try {
    uni.removeStorageSync(TOKEN_KEY);
    uni.removeStorageSync(REFRESH_TOKEN_KEY);
    console.log('清除token成功');
  } catch (e) {
    console.error('清除token失败:', e);
  }
};

export const hasToken = () => {
  const token = getToken();
  // 严格验证：token存在且不是空字符串
  const hasValidToken = !!token && token.trim() !== '';
  console.log('是否有有效token:', hasValidToken);
  return hasValidToken;
};

// 拦截器管理
let requestInterceptors = [];
let responseInterceptors = [];

export const addRequestInterceptor = (interceptor) => {
  requestInterceptors.push(interceptor);
};

export const addResponseInterceptor = (interceptor) => {
  responseInterceptors.push(interceptor);
};

export const configure = (config) => {
  currentConfig = { ...currentConfig, ...config };
};

// 核心请求函数
const request = (options) => {
  return new Promise((resolve, reject) => {
    // 合并配置
    const opts = { ...currentConfig, ...options };

    // 处理URL
    opts.url = opts.baseURL && !opts.url.startsWith('http') 
      ? opts.baseURL + opts.url 
      : opts.url;
    opts.relativeUrl = opts.url.replace(opts.baseURL, ''); // 相对路径用于判断是否需要token

    // 显示加载提示
    if (opts.showLoading) {
      uni.showLoading({
        title: opts.loadingTitle,
        mask: true
      });
    }

    // 应用请求拦截器
    let interceptedOptions = { ...opts };
    requestInterceptors.forEach(interceptor => {
      interceptedOptions = interceptor(interceptedOptions) || interceptedOptions;
    });

    // 添加Token到请求头（核心修复点：强化逻辑）
    const needToken = !excludeList.includes(opts.relativeUrl);
    if (needToken && !interceptedOptions.header['Authorization']) {
      if (hasToken()) {
        interceptedOptions.header.Authorization = ` ${getToken()}`;
        console.log(`为接口[${opts.relativeUrl}]添加token`);
      } else {
        console.warn(`接口[${opts.relativeUrl}]需要token，但未获取到`);
        // 未获取到token时，直接触发登录跳转（避免无效请求）
        if (!isRefreshing) {
          handleTokenExpired(options, resolve, reject);
          return; // 终止当前请求处理
        }
      }
    }

    // 处理请求方法和参数
    const method = (interceptedOptions.method || 'GET').toUpperCase();
    const requestData = {
      url: interceptedOptions.url,
      method,
      header: interceptedOptions.header,
      timeout: interceptedOptions.timeout,
      [method == 'GET' ? 'params' : 'data']: interceptedOptions.param || interceptedOptions.data || {}
    };

    // 发送请求
    uni.request({
      ...requestData,
      success: async (res) => {
        // 隐藏加载提示
        if (opts.showLoading) {
          uni.hideLoading();
        }

        // 处理登录接口的token存储（核心修复点：确保存储成功后再继续）
        if (excludeList.includes(opts.relativeUrl)) {
          // 等待token存储完成
          await dealRequestData(opts.relativeUrl, res);
        }

        // 应用响应拦截器
        let interceptedResponse = { ...res };
        for (const interceptor of responseInterceptors) {
          const result = await interceptor(interceptedResponse);
          if (result) {
            interceptedResponse = result;
          }
        }

        const { statusCode, data } = interceptedResponse;

        // HTTP状态码处理
        if (statusCode >= 200 && statusCode < 300) {
          // 业务状态码处理
          const { code, msg } = data;

          // 成功状态
          if (code == 0 || code == 200) {
            resolve(data.result || data);
          }
          // Token失效（未授权）
          else if (code == 'A00006' || code == 'A00004') {
            handleTokenExpired(options, resolve, reject);
          }
          // 其他业务错误
          else {
            showErrorToast(msg || `请求失败: ${code}`);
            reject(data);
          }
        }
        // HTTP错误
        else {
          showErrorToast(`网络错误: ${statusCode}`);
          reject(res);
        }
      },
      fail: (err) => {
        if (opts.showLoading) {
          uni.hideLoading();
        }
        showErrorToast('网络连接失败，请检查网络');
        reject(err);
      }
    });
  });
};

// 错误提示
const showErrorToast = (message) => {
  uni.showToast({
    title: message,
    icon: 'none',
    duration: 2000
  });
};

// 处理Token过期
const handleTokenExpired = (options, resolve, reject) => {
  if (!isRefreshing) {
    isRefreshing = true;
    
    // 尝试用refresh_token刷新token
    refreshToken().then(newToken => {
      setToken(newToken);
      requests.forEach(cb => cb(newToken));
      requests = [];
      request(options).then(resolve).catch(reject);
    }).catch(() => {
      removeToken();
      requests = [];
      // 跳转到登录页（确保跳转前清除所有token）
      const currentPages = getCurrentPages();
      if (!currentPages.some(page => page.route == 'pages/login/login')) {
        // 延迟跳转，确保token已清除
        setTimeout(() => {
          uni.navigateTo({ url: '/pages/login/login' });
        }, 300);
      }
      reject('token已过期，请重新登录');
    }).finally(() => {
      isRefreshing = false;
    });
  } else {
    requests.push((newToken) => {
      options.header = {
        ...options.header,
        Authorization: ` ${newToken}`
      };
      request(options).then(resolve).catch(reject);
    });
  }
};

// 刷新Token的请求
const refreshToken = () => {
  return new Promise((resolve, reject) => {
    const refreshToken = getRefreshToken();
    if (!refreshToken) {
      reject('没有refresh_token');
      return;
    }

    uni.request({
      url: currentConfig.baseURL + '/api/auth/refresh-token',
      method: 'POST',
      header: {
        'Content-Type': 'application/json',
        'Authorization': ` ${refreshToken}`
      },
      success: (res) => {
        if (res.statusCode == 200 && res.data.code == 0) {
          const { accessToken, refreshToken } = res.data.data || {};
          if (accessToken) {
            setToken(accessToken);
            if (refreshToken) {
              setRefreshToken(refreshToken);
            }
            resolve(accessToken);
          } else {
            reject('刷新token失败，返回格式不正确');
          }
        } else {
          reject(`刷新token失败: ${res.data?.msg || res.statusCode}`);
        }
      },
      fail: (err) => {
        reject('刷新token请求失败: ' + err.errMsg);
      }
    });
  });
};

// 处理返回值（核心修复点：确保登录后token正确存储）
const dealRequestData = (url, res) => {
  return new Promise((resolve) => { // 用Promise确保存储完成
    if (url == '/admin/login/password') {
      console.log('登录接口响应:', res.data); // 打印完整响应，便于调试
      if (res.data?.code == 0) {
        // 关键：根据实际接口返回的字段名调整（这里是最可能出问题的地方）
        // 如果你后端返回的是{data: {token: 'xxx', refreshToken: 'yyy'}}，则需要改成const { token, refreshToken } = ...
        const { accessToken, refreshToken } = res.data.data || {};
        
        // 验证token是否有效
        if (!accessToken || !refreshToken) {
          console.error('登录接口返回的token不完整', { accessToken, refreshToken });
          resolve();
          return;
        }
        
        // 存储token（同步操作）
        setToken(accessToken);
        setRefreshToken(refreshToken);
        
        // 验证存储结果
        const storedToken = getToken();
        if (storedToken === accessToken) {
          console.log('登录后token存储验证成功');
        } else {
          console.error('登录后token存储验证失败', {
            expected: accessToken.substring(0, 10) + '...',
            actual: storedToken.substring(0, 10) + '...'
          });
        }
      } else {
        console.error('登录失败，不存储token', res.data?.msg);
      }
    }
    resolve();
  });
};

// 导出默认实例
export default request;
